﻿using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Configuration;
using System.Threading;
using System.Management;
using System.Net;
using System.ServiceProcess;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

using FundSms.Client.BLL;
using FundSms.Client.Model;
using FundSms.SmsLib;

namespace SmsClient
{
    public class Program : ServiceBase
    {
        private static string ServerIP = ConfigurationManager.AppSettings["ServerIP"];
        private static int ServerPort = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
        private static int EnableLogTable = Convert.ToInt32(ConfigurationManager.AppSettings["EnableLogTable"]);
        private static int WorkThreads = Convert.ToInt32(ConfigurationManager.AppSettings["WorkThreads"]);
        private static int SendCountPerTime = Convert.ToInt32(ConfigurationManager.AppSettings["SendCountPerTime"]);
        private static int ReceiveCountPerTime = Convert.ToInt32(ConfigurationManager.AppSettings["ReceiveCountPerTime"]);
        private static int SleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["SleepTime"]);
        private static int ValidateTime = Convert.ToInt32(ConfigurationManager.AppSettings["ValidateTime"]) * 1000;
        private static int BlackKeyTime = Convert.ToInt32(ConfigurationManager.AppSettings["BlackKeyTime"]) * 1000;
        private static string EnterpriseCode = ConfigurationManager.AppSettings["EnterpriseCode"];
        private static string EnterpriseAccount = ConfigurationManager.AppSettings["EnterpriseAccount"];
        private static string EnterprisePassword = ConfigurationManager.AppSettings["EnterprisePassword"];
        private static string ServerURL = "tcp://" + ServerIP + ":" + ServerPort + "/RemoteObject";
        private static bool LogToFile = ConfigurationManager.AppSettings["LogToFile"] == "1" ? true : false;
        private static string ServiceRealName = ConfigurationManager.AppSettings["ServiceName"];
        private static string ServiceDisPlayName = ConfigurationManager.AppSettings["ServiceDisPlayName"];
        private static string ServiceDescription = ConfigurationManager.AppSettings["ServiceDescription"];

        private static object lockobj = new object();

        private static string IP = GetIPAddress();
        private static string MAC = GetMacAddress();

        private static string BlackList = string.Empty;
        private static string BlackListGlobal = string.Empty;
        private static SortedList<string, string> KeyWordsList = new SortedList<string, string>();

        //服务所在路径
        private static string ServicePath = Application.ExecutablePath;
        private static string ServiceDirectory = Path.GetDirectoryName(ServicePath);

        private static FundSms.RemoteObject.RemoteObject obj;

        //身份验证
        private static bool Valid = false;
        //定时身份检查
        private static System.Timers.Timer CheckUpdatetimer = new System.Timers.Timer();
        //黑名单关键字刷新
        private static System.Timers.Timer timerBlackKey = new System.Timers.Timer();
        //单线程
        private static Thread t;
        //多线程
        private static Thread[] threads;

        //状态线程
        private static Thread threadStatus;
        //上行线程
        private static Thread threadMO;


        //调试模式开关
        private static int Debug = 0;
        //服务是否停止开关
        private static bool Stopped = false;

        private static bool CanStopped = false;

        private static Dictionary<string, bool> DicStatus = new Dictionary<string, bool>();


        #region 应用程序入口
        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            bool exists = ServiceControl.CheckService(ServiceRealName);

            if (args.Length == 0)
            {
                ServiceBase.Run(new ServiceBase[] { new Program() });
            }
            else
            {
                string parm = args[0].ToLower();

                switch (parm)
                {
                    case "-debug":
                    case "/debug":

                        Debug = 1;

                        if (exists)
                        {
                            ServiceControllerStatus status = ServiceControl.GetServiceStatus(ServiceRealName);

                            if (status != ServiceControllerStatus.Stopped)
                            {
                                Console.WriteLine(GetDateTime() + ServiceRealName + " 服务正在运行，无法进入调试状态。请先停止该服务");
                                Console.WriteLine(GetDateTime() + "请关闭本窗体");
                                Console.ReadLine();
                            }
                            else
                            {
                                InitilizeCompoment();
                            }
                        }
                        else
                        {
                            InitilizeCompoment();
                        }


                        break;

                    case "-install":
                    case "-setup":
                    case "/install":
                    case "/setup":

                        if (exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务已经存在，如果您想升级服务，请先卸载该服务");
                            Console.WriteLine(GetDateTime() + "请关闭本窗体");
                            Console.ReadLine();
                        }
                        else
                        {
                            Console.WriteLine(GetDateTime() + ServicePath);

                            bool result = ServiceControl.InstallService(ServicePath, ServiceRealName, ServiceDisPlayName, ServiceDescription);

                            if (result)
                            {
                                Console.WriteLine(GetDateTime() + "服务安装成功");
                                Console.WriteLine(GetDateTime() + "正在启动服务...");

                                ServiceControl.StartService(ServiceRealName);

                                while (!(ServiceControl.GetServiceStatus(ServiceRealName) == ServiceControllerStatus.Running))
                                {
                                    Thread.Sleep(SleepTime);
                                }

                                Console.WriteLine(GetDateTime() + "服务已经启动");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务安装失败");
                            }

                            Console.WriteLine(GetDateTime() + "请关闭本窗体");
                            Console.ReadLine();
                        }
                        break;

                    case "-uninstall":
                    case "-remove":
                    case "/uninstall":
                    case "/remove":

                        if (!exists)
                        {
                            Console.WriteLine(GetDateTime() + ServiceRealName + " 服务尚未安装");
                        }
                        else
                        {
                            bool result = ServiceControl.UnInstallService(ServiceRealName);

                            if (!result)
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载失败");
                            }
                            else
                            {
                                Console.WriteLine(GetDateTime() + "服务卸载成功");
                            }
                        }

                        Console.WriteLine(GetDateTime() + "请关闭本窗体");
                        Console.ReadLine();

                        break;

                }

            }
        }

        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Output("未处理A：" + e.Exception.Message, ConsoleColor.Red, true);
        }

        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.ExceptionObject is System.Exception)
            {
                Output("未处理P：" + ((System.Exception)e.ExceptionObject).Message, ConsoleColor.Red, true);
            } 

        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

            }

            base.Dispose(disposing);
        }

        public Program()
        {
            base.ServiceName = ServiceRealName;
            base.AutoLog = true;
        }

        #endregion

        #region 初始化服务设置
        protected override void OnStart(string[] args)
        {
            InitilizeCompoment();
        }

        protected override void OnStop()
        {
            //停止定时器
            CheckUpdatetimer.Enabled = false;

            Stopped = true;

            try
            {

                if (WorkThreads == 1)
                {
                    while (!CanStopped)
                    {
                        Thread.Sleep(SleepTime);
                    }
                }
                else
                {
                    while (!AllStop())
                    {
                        Thread.Sleep(SleepTime);
                    }
                }
            }
            catch
            {
            }

        }

        /// <summary>
        /// 判断工作线程是否已经都停止了
        /// </summary>
        /// <returns></returns>
        private static bool AllStop()
        {
            try
            {
                lock (lockobj)
                {
                    foreach (bool value in DicStatus.Values)
                    {
                        if (!value)
                        {
                            return false;
                        }
                    }
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region 应用程序初始化
        private static void InitilizeCompoment()
        {
            if (Debug == 1)
            {
                Console.Title = ServiceDisPlayName;
            }

            if (ValidateTime < 5000)
            {
                ValidateTime = 5000;
            }

            if (WorkThreads > 10)
            {
                WorkThreads = 10;
            }

            if (WorkThreads < 1)
            {
                WorkThreads = 1;
            }

            Output("IP：" + IP);
            Output("MAC：" + MAC);
            Output("开始发送数据");

            obj = CreateRemoteObject();

            if (obj == null)
            {
                Output("无法连接远程服务器", ConsoleColor.Red, true);
                return;
            }

            //验证用户登录信息
            int loginresult = -99;

            try
            {
                loginresult = obj.Login(EnterpriseCode, EnterpriseAccount, EnterprisePassword, IP, MAC);
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red);
            }

            if (loginresult > 0)
            {
                Valid = true;
            }
            else
            {
                Output(GetErrorMessage(loginresult));
            }

            try
            {
                BlackList = obj.GetBlackList(EnterpriseCode);

                if (BlackList != string.Empty)
                {
                    BlackList = Compress.UnzipString(BlackList);
                }

                Output("获取本企业黑名单");
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red);
            }

            try
            {
                BlackListGlobal = obj.GetBlackList();

                if (BlackListGlobal != string.Empty)
                {
                    BlackListGlobal = Compress.UnzipString(BlackListGlobal);
                }

                Output("获取全局黑名单");
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red);
            }

            try
            {
                string KeyWords = obj.GetKeyWords();

                if (KeyWords != string.Empty)
                {
                    KeyWords = Compress.UnzipString(KeyWords);

                    string[] KeyWordsArr = KeyWords.Split(',');

                    KeyWordsList.Clear();

                    for (int i = 0; i < KeyWordsArr.Length; i++)
                    {
                        KeyWordsList.Add(KeyWordsArr[i], KeyWordsArr[i]);
                    }
                }

                Output("获取屏蔽关键字");
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red);
            }


            InitilizeTimer();

            //开始发送数据
            if (WorkThreads == 1)
            {
                t = new Thread(SendSms);
                t.IsBackground = false;
                t.Start();
            }
            else
            {
                threads = new Thread[WorkThreads];

                DicStatus.Clear();

                for (int i = 0; i < WorkThreads; i++)
                {
                    DicStatus.Add("Threads" + (i + 1).ToString(), false);

                    threads[i] = new Thread(new ParameterizedThreadStart(SendSmsMulti));
                    threads[i].IsBackground = false;
                    threads[i].Name = "Threads" + (i + 1).ToString();
                    threads[i].Start(i);
                }
            }

            threadStatus = new Thread(ReceiveStatus);
            threadStatus.Start();

            threadMO = new Thread(ReceiveMO);
            threadMO.Start();

            if (Debug == 1)
            {
                Console.ReadLine();
            }
        }
        #endregion

        #region 初始化定时器
        /// <summary>
        /// 初始化定时器
        /// </summary>
        private static void InitilizeTimer()
        {
            // 循环间隔时间(10分钟)
            CheckUpdatetimer.Interval = ValidateTime;
            // 允许Timer执行
            CheckUpdatetimer.Enabled = true;
            // 定义回调
            CheckUpdatetimer.Elapsed += new System.Timers.ElapsedEventHandler(CheckUpdatetimer_Elapsed);
            // 定义多次循环
            CheckUpdatetimer.AutoReset = true;

            // 循环间隔时间(10分钟)
            timerBlackKey.Interval = BlackKeyTime;
            // 允许Timer执行
            timerBlackKey.Enabled = true;
            // 定义回调
            timerBlackKey.Elapsed += new System.Timers.ElapsedEventHandler(timerBlackKey_Elapsed);
            // 定义多次循环
            timerBlackKey.AutoReset = true;
        }

        static void timerBlackKey_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            #region 黑名单和关键字
            try
            {
                BlackList = obj.GetBlackList(EnterpriseCode);

                if (BlackList != string.Empty)
                {
                    BlackList = Compress.UnzipString(BlackList);
                }

                Output("获取本企业黑名单");
            }
            catch (Exception e1)
            {
                Output(e1.Message + "\r\n" + e1.StackTrace, ConsoleColor.Red);
            }

            try
            {
                BlackListGlobal = obj.GetBlackList();

                if (BlackListGlobal != string.Empty)
                {
                    BlackListGlobal = Compress.UnzipString(BlackListGlobal);
                }

                Output("获取全局黑名单");
            }
            catch (Exception e1)
            {
                Output(e1.Message + "\r\n" + e1.StackTrace, ConsoleColor.Red);
            }

            try
            {
                string KeyWords = obj.GetKeyWords();

                if (KeyWords != string.Empty)
                {
                    KeyWords = Compress.UnzipString(KeyWords);

                    string[] KeyWordsArr = KeyWords.Split(',');

                    KeyWordsList.Clear();

                    for (int i = 0; i < KeyWordsArr.Length; i++)
                    {
                        KeyWordsList.Add(KeyWordsArr[i], KeyWordsArr[i]);
                    }
                }

                Output("获取屏蔽关键字");
            }
            catch (Exception e1)
            {
                Output(e1.Message + "\r\n" + e1.StackTrace, ConsoleColor.Red);
            }
            #endregion
        }
        #endregion

        #region 定时器

        static void CheckUpdatetimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (Debug == 1)
            {
                Console.Clear();
            }

            Output("验证身份信息");

            int loginresult = -99;

            try
            {
                loginresult = obj.Login(EnterpriseCode, EnterpriseAccount, EnterprisePassword, IP, MAC);
            }
            catch (Exception e1)
            {
                Output(e1.Message + "\r\n" + e1.StackTrace,ConsoleColor.Red,true);
            }

            try
            {
                if (loginresult > 0)
                {
                    Valid = true;
                }
                else
                {
                    Valid = false;

                    Output(GetErrorMessage(loginresult),true);
                }
            }
            catch(Exception e1)
            {
                Output(e1.Message + "\r\n" + e1.StackTrace, ConsoleColor.Red, true);
            }
        }

        #endregion

        #region 远程对象
        private static FundSms.RemoteObject.RemoteObject CreateRemoteObject()
        {
            try
            {
                ChannelServices.RegisterChannel(new TcpClientChannel(), false);
                FundSms.RemoteObject.RemoteObject obj = (FundSms.RemoteObject.RemoteObject)Activator.GetObject(typeof(FundSms.RemoteObject.RemoteObject), ServerURL);

                return obj;
            }
            catch (Exception e)
            {
                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
            }

            return null;
        }
        #endregion

        #region 发送逻辑

        private static void SendSms()
        {
            SmsSendList send = new SmsSendList();
            SmsReturn ret = new SmsReturn();
            SmsSendLog log = new SmsSendLog();

            //返回信息
            TSMSReturnHundSunInfo retinfo = new TSMSReturnHundSunInfo();
            //日志信息
            TSMSSendLogInfo loginfo = new TSMSSendLogInfo();

            IList<TSMSSendHundSunInfo> sendlist;

            Dictionary<string, TSMSSendHundSunInfo> senddic = null;

            string result = string.Empty;
            string zipresult = string.Empty;

            while (true)
            {
                if (Stopped)
                {
                    CanStopped = true;

                    break;
                }

                if (!Valid)
                {
                    Output("身份验证失败", ConsoleColor.Red);

                    Thread.Sleep(ValidateTime);

                    continue;
                }

                try
                {
                    sendlist = send.GetSendList(SendCountPerTime);
                }
                catch(Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);

                    Thread.Sleep(SleepTime);

                    continue;
                }

                if (sendlist.Count == 0)
                {
                    //Output("没有待发数据", ConsoleColor.Blue);

                    Thread.Sleep(SleepTime);

                    continue;
                }
                else
                {
                    senddic = new Dictionary<string, TSMSSendHundSunInfo>();

                    StringBuilder sb = new StringBuilder();

                    foreach (TSMSSendHundSunInfo sms in sendlist)
                    {
                        //判断是否是合法短信
                        if (ValidSms(sms))
                        {
                            sb.Append(sms.ToString() + "\n");

                            senddic.Add(sms.LSerialno.ToString(), sms);
                        }
                    }

                    result = sb.ToString();

                    if (result != string.Empty)
                    {
                        result = result.Substring(0, result.Length - 2);
                        zipresult = Compress.ZipString(result);

                        sendlist.Clear();
                        sendlist = null;
                    }
                    else
                    {
                        Thread.Sleep(SleepTime);

                        continue;
                    }
                }

                string sendresult = string.Empty;

                try
                {
                    sendresult = obj.Send(EnterpriseCode,EnterpriseAccount,zipresult);

                    Output("发送 " + senddic.Count.ToString() + " 数据");
                }
                catch(Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red);
                }

                if (sendresult != string.Empty)
                {
                    sendresult = Compress.UnzipString(sendresult);

                    string[] arr = sendresult.Split(',');

                    for (int i = 0; i < arr.Length;i++ )
                    {
                        if (senddic.ContainsKey(arr[i]))
                        {
                            TSMSSendHundSunInfo sms = senddic[arr[i]];
                            //从待发表里删除
                            try
                            {
                                send.DeleteSms(sms.LSerialno);
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                                continue;
                            }

                            //插入状态表
                            retinfo.CContent = sms.CContent;
                            retinfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                            retinfo.CFrom = sms.CFrom;
                            retinfo.CHandle = "0";
                            retinfo.CMobile = sms.CMobileno;
                            retinfo.CProperty = sms.CProperty;
                            retinfo.CR1 = sms.CR1;
                            retinfo.CR2 = sms.CR2;
                            retinfo.CR3 = sms.CR3;
                            retinfo.CR4 = sms.CR4;
                            retinfo.CR5 = sms.CR5;
                            retinfo.CReturn = string.Empty;
                            retinfo.CReturnTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            retinfo.CSmsID = sms.CSmsID;
                            retinfo.CSmsName = sms.CSmsname;

                            try
                            {
                                ret.Insert(retinfo);
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                            }

                            if (EnableLogTable == 1)
                            {
                                //插入日志表
                                loginfo.CContent = sms.CContent;
                                loginfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                                loginfo.CFrom = sms.CFrom;
                                loginfo.CHanlde = "0";
                                loginfo.CLogTime = DateTime.Now;
                                loginfo.CMobileno = sms.CMobileno;
                                loginfo.CProperty = sms.CProperty;
                                loginfo.CR1 = sms.CR1;
                                loginfo.CR2 = sms.CR2;
                                loginfo.CR3 = sms.CR3;
                                loginfo.CR4 = sms.CR4;
                                loginfo.CR5 = sms.CR5;
                                loginfo.CSmsID = sms.CSmsID;
                                loginfo.CSmsname = sms.CSmsname;

                                try
                                {
                                    log.Insert(loginfo);
                                }
                                catch (Exception e)
                                {
                                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                                }
                            }

                        }
                        
                    }
                }

                Thread.Sleep(SleepTime);
            }
        }

        private static void SendSmsMulti(object o)
        {
            int mod = (int)o;

            string threadname = "Threads" + (mod + 1).ToString();

            SmsSendList send = new SmsSendList();
            SmsReturn ret = new SmsReturn();
            SmsSendLog log = new SmsSendLog();

            //返回信息
            TSMSReturnHundSunInfo retinfo = new TSMSReturnHundSunInfo();
            //日志信息
            TSMSSendLogInfo loginfo = new TSMSSendLogInfo();

            IList<TSMSSendHundSunInfo> sendlist;

            Dictionary<string, TSMSSendHundSunInfo> senddic = null;

            string result = string.Empty;
            string zipresult = string.Empty;

            while (true)
            {
                if (Stopped)
                {
                    lock (lockobj)
                    {
                        DicStatus[threadname] = true;
                    }

                    break;
                }

                if (!Valid)
                {
                    Output("身份验证失败", ConsoleColor.Red);

                    Thread.Sleep(ValidateTime);

                    continue;
                }

                try
                {
                    sendlist = send.GetSendList(SendCountPerTime, WorkThreads, mod);
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);

                    Thread.Sleep(SleepTime);

                    continue;
                }

                if (sendlist.Count == 0)
                {
                    //Output("没有待发数据，" + Thread.CurrentThread.Name, ConsoleColor.Blue);

                    Thread.Sleep(SleepTime);

                    continue;
                }
                else
                {
                    senddic = new Dictionary<string, TSMSSendHundSunInfo>();

                    StringBuilder sb = new StringBuilder();

                    foreach (TSMSSendHundSunInfo sms in sendlist)
                    {
                        //判断是否是合法短信
                        if (ValidSms(sms))
                        {
                            sb.Append(sms.ToString() + "\n");

                            senddic.Add(sms.LSerialno.ToString(), sms);
                        }
                    }

                    result = sb.ToString();

                    if (result != string.Empty)
                    {
                        result = result.Substring(0, result.Length - 2);
                        zipresult = Compress.ZipString(result);

                        sendlist.Clear();
                        sendlist = null;
                    }
                    else
                    {
                        Thread.Sleep(SleepTime);

                        continue;
                    }
                }

                string sendresult = string.Empty;

                try
                {
                    sendresult = obj.Send(EnterpriseCode, EnterpriseAccount, zipresult);

                    Output("发送 " + senddic.Count.ToString() + " 数据，" + Thread.CurrentThread.Name);
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                }

                if (sendresult != string.Empty)
                {

                    sendresult = Compress.UnzipString(sendresult);

                    string[] arr = sendresult.Split(',');

                    for (int i = 0; i < arr.Length;i++ )
                    {
                        if (senddic.ContainsKey(arr[i]))
                        {
                            TSMSSendHundSunInfo sms = senddic[arr[i]];
                            //从待发表里删除
                            try
                            {
                                send.DeleteSms(sms.LSerialno);
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);

                                continue;
                            }

                            //插入状态表
                            retinfo.CContent = sms.CContent;
                            retinfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                            retinfo.CFrom = sms.CFrom;
                            retinfo.CHandle = "0";
                            retinfo.CMobile = sms.CMobileno;
                            retinfo.CProperty = sms.CProperty;
                            retinfo.CR1 = sms.CR1;
                            retinfo.CR2 = sms.CR2;
                            retinfo.CR3 = sms.CR3;
                            retinfo.CR4 = sms.CR4;
                            retinfo.CR5 = sms.CR5;
                            retinfo.CReturn = string.Empty;
                            retinfo.CReturnTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            retinfo.CSmsID = sms.CSmsID;
                            retinfo.CSmsName = sms.CSmsname;

                            try
                            {
                                ret.Insert(retinfo);
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                            }

                            if (EnableLogTable == 1)
                            {
                                //插入日志表
                                loginfo.CContent = sms.CContent;
                                loginfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                                loginfo.CFrom = sms.CFrom;
                                loginfo.CHanlde = "0";
                                loginfo.CLogTime = DateTime.Now;
                                loginfo.CMobileno = sms.CMobileno;
                                loginfo.CProperty = sms.CProperty;
                                loginfo.CR1 = sms.CR1;
                                loginfo.CR2 = sms.CR2;
                                loginfo.CR3 = sms.CR3;
                                loginfo.CR4 = sms.CR4;
                                loginfo.CR5 = sms.CR5;
                                loginfo.CSmsID = sms.CSmsID;
                                loginfo.CSmsname = sms.CSmsname;

                                try
                                {
                                    log.Insert(loginfo);
                                }
                                catch (Exception e)
                                {
                                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                                }
                            }
                        }
                    }
                }

                Thread.Sleep(SleepTime);
            }
        }

        /// <summary>
        /// 判断本条短信是否合法
        /// </summary>
        /// <param name="sms"></param>
        /// <returns></returns>
        private static bool ValidSms(TSMSSendHundSunInfo sms)
        {
            bool result = true;
            string status = string.Empty;

            if (BlackList.IndexOf(sms.CMobileno) >= 0)
            {
                result = false;
                status = "b";
            }

            if (BlackListGlobal.IndexOf(sms.CMobileno) >= 0)
            {
                result = false;
                status = "b";
            }

            foreach (string value in KeyWordsList.Values)
            {
                if (sms.CContent.IndexOf(value) >= 0)
                {
                    result = false;
                    status = "k";
                    break;
                }
            }

            if (!result)
            {
                SmsSendList send = new SmsSendList();
                SmsReturn ret = new SmsReturn();
                SmsSendLog log = new SmsSendLog();

                //返回信息
                TSMSReturnHundSunInfo retinfo = new TSMSReturnHundSunInfo();
                //日志信息
                TSMSSendLogInfo loginfo = new TSMSSendLogInfo();

                //从待发表里删除
                try
                {
                    send.DeleteSms(sms.LSerialno);
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                }

                //插入状态表
                retinfo.CContent = sms.CContent;
                retinfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                retinfo.CFrom = sms.CFrom;
                retinfo.CHandle = "0";
                retinfo.CMobile = sms.CMobileno;
                retinfo.CProperty = sms.CProperty;
                retinfo.CR1 = sms.CR1;
                retinfo.CR2 = sms.CR2;
                retinfo.CR3 = sms.CR3;
                retinfo.CR4 = sms.CR4;
                retinfo.CR5 = sms.CR5;
                retinfo.CReturn = status;
                retinfo.CReturnTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                retinfo.CSmsID = sms.CSmsID;
                retinfo.CSmsName = sms.CSmsname;

                try
                {
                    ret.Insert(retinfo);
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                }

                if (EnableLogTable == 1)
                {
                    //插入日志表
                    loginfo.CContent = sms.CContent;
                    loginfo.CDate = sms.CDate.ToString("yyyy-MM-dd HH:mm:ss");
                    loginfo.CFrom = sms.CFrom;
                    loginfo.CHanlde = "0";
                    loginfo.CLogTime = DateTime.Now;
                    loginfo.CMobileno = sms.CMobileno;
                    loginfo.CProperty = sms.CProperty;
                    loginfo.CR1 = sms.CR1;
                    loginfo.CR2 = sms.CR2;
                    loginfo.CR3 = sms.CR3;
                    loginfo.CR4 = sms.CR4;
                    loginfo.CR5 = sms.CR5;
                    loginfo.CSmsID = sms.CSmsID;
                    loginfo.CSmsname = sms.CSmsname;

                    try
                    {
                        log.Insert(loginfo);
                    }
                    catch (Exception e)
                    {
                        Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red, true);
                    }
                }
            }

            return result;

        }
        #endregion

        #region 状态和上行逻辑
        /// <summary>
        /// 接收状态
        /// </summary>
        private static void ReceiveStatus()
        {
            SmsReturn smsreturn = new SmsReturn();
            string smslist = string.Empty;
            StringBuilder sb = null;

            while (true)
            {
                if (Stopped)
                {
                    break;
                }

                if (!Valid)
                {
                    Output("身份验证失败", ConsoleColor.Red);

                    Thread.Sleep(ValidateTime);

                    continue;
                }

                sb = new StringBuilder();

                try
                {
                    smslist = obj.GetSmsStatus(EnterpriseCode, EnterpriseAccount, ReceiveCountPerTime);
                }
                catch(Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                }

                if (smslist != string.Empty)
                {
                    smslist = Compress.UnzipString(smslist);

                    string[] arr = Regex.Split(smslist, "\n");

                    if (arr.Length > 0)
                    {
                        for (int i = 0; i < arr.Length; i++)
                        {
                            string[] row = arr[i].Split('|');
                            string logid = row[0];
                            string smsid = row[1];
                            string mobile = row[2];
                            string result = row[3];

                            try
                            {
                                smsreturn.UpdateStatus(result, smsid, mobile);

                                sb.Append(logid + ",");
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                            }
                        }

                        Output("更新" + arr.Length + "状态", ConsoleColor.Blue);
                    }

                    string loglist = sb.ToString();

                    if (loglist != string.Empty)
                    {
                        loglist = loglist.Substring(0, loglist.Length - 1);

                        try
                        {
                            obj.UpdateSmsStatus(EnterpriseCode, EnterpriseAccount, Compress.ZipString(loglist));
                        }
                        catch (Exception e)
                        {
                            Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                        }
                    }
                }

                Thread.Sleep(SleepTime);
            }
        }

        private static void ReceiveMO()
        {
            SmsMO mo = new SmsMO();
            TSMSMOInfo moinfo = null;
            StringBuilder sb = null;
            string molist = string.Empty;

            while (true)
            {
                if (Stopped)
                {
                    break;
                }

                if (!Valid)
                {
                    Output("身份验证失败", ConsoleColor.Red);

                    Thread.Sleep(ValidateTime);

                    continue;
                }

                sb = new StringBuilder();

                try
                {
                    molist = obj.GetMO(EnterpriseCode, EnterpriseAccount);
                }
                catch (Exception e)
                {
                    Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                }

                if (molist != string.Empty)
                {
                    molist = Compress.UnzipString(molist);

                    string[] arr = Regex.Split(molist, "\n");

                    if (arr.Length > 0)
                    {
                        for (int i = 0; i < arr.Length; i++)
                        {
                            string[] row = arr[i].Split('|');

                            string logid = row[0];
                            string mobile = row[1];
                            string servicecode = row[2];
                            string content = StringEX.ConvertDesSpecialCharacter(row[3]);
                            string datetime = row[4];

                            if (content == string.Empty)
                            {
                                content = " ";
                            }

                            moinfo = new TSMSMOInfo(0,mobile,servicecode,content,datetime,"0");

                            try
                            {
                                mo.Insert(moinfo);

                                sb.Append(logid + ",");
                            }
                            catch (Exception e)
                            {
                                Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                            }
                        }

                        Output("接收" + arr.Length + "上行", ConsoleColor.Green);
                    }

                    string loglist = sb.ToString();

                    if (loglist != string.Empty)
                    {
                        loglist = loglist.Substring(0, loglist.Length - 1);

                        try
                        {
                            obj.UpdateMO(EnterpriseCode, EnterpriseAccount, Compress.ZipString(loglist));
                        }
                        catch (Exception e)
                        {
                            Output(e.Message + "\r\n" + e.StackTrace, ConsoleColor.Red,true);
                        }
                    }
                }

                Thread.Sleep(SleepTime);
            }
        }

        #endregion

        #region 调试辅助逻辑
        private static string GetDateTime()
        {
            return "[" + DateTime.Now.ToString("HH:mm:ss") + "] ";
        }

        private static void Output(string msg)
        {
            lock (lockobj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }
            }
        }

        private static void Output(string msg, bool log)
        {
            lock (lockobj)
            {
                if (Debug == 1)
                {
                    Console.WriteLine(GetDateTime() + msg);
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }

        private static void Output(string msg, ConsoleColor color)
        {
            lock (lockobj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }
            }
        }

        private static void Output(string msg, ConsoleColor color, bool log)
        {
            lock (lockobj)
            {
                if (Debug == 1)
                {
                    Console.ForegroundColor = color;
                    Console.WriteLine(GetDateTime() + msg);
                    Console.ResetColor();
                }

                if (log)
                {
                    if (LogToFile)
                    {
                        Log.WriteToFile(ServiceDirectory + @"\log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", GetDateTime() + msg);
                    }
                }
            }
        }
        #endregion

        #region 获得IP地址
        private static string GetIPAddress()
        {
            
            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());

            string ip = string.Empty;

            for (int i = 0; i < ips.Length; i++)
            {
                ip += ips[i].ToString() + ",";
            }

            if (ip != string.Empty)
            {
                ip = ip.Substring(0, ip.Length - 1);
            }

            return ip;
            
            /*
            string ip = string.Empty;
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                if ((bool)mo["IPEnabled"] == true)
                {
                    string[] ipaddresses = (string[])mo["IPAddress"];

                    for (int i = 0; i < ipaddresses.Length; i++)
                    {
                        ip += ipaddresses[i].ToString() + ",";
                    }
                }
            }

            if (ip != string.Empty)
            {
                ip = ip.Substring(0, ip.Length - 1);
            }

            return ip;
           */

        }
        #endregion

        #region 获得MAC
        private static string GetMacAddress()
        {
            ManagementClass adapters = new ManagementClass("Win32_NetworkAdapterConfiguration");
            string MACAddress = string.Empty;
            foreach (ManagementObject adapter in adapters.GetInstances())
            {
                if ((bool)adapter["IPEnabled"] == true)
                {
                    MACAddress = adapter.Properties["MACAddress"].Value.ToString();
                    MACAddress += ",";
                }
            }

            //去除最后一个,号
            if (MACAddress != string.Empty)
            {
                MACAddress = MACAddress.Substring(0, MACAddress.Length - 1);
            }

            return MACAddress;
        }
        #endregion

        #region 身份验证
        private static string GetErrorMessage(int code)
        {
            if (code == -100)
            {
                return "服务器内部错误";
            }
            else if (code == -99)
            {
                return "无法链接服务器";
            }
            else if (code == -1)
            {
                return "企业号、用户名、密码不匹配";
            }
            else if (code == -2)
            {
                return "帐号已经被停用";
            }
            else if (code == -3)
            {
                return "IP校验失败";
            }
            else if (code == -4)
            {
                return "IP地址不正确";
            }
            else if (code == -5)
            {
                return "MAC校验失败";
            }
            else if (code == -6)
            {
                return "MAC不正确";
            }

            return "未知错误";
        }
        #endregion
    }
}
